package com.zmn.oms.business.impl.messageV1.wechat;

import com.alibaba.fastjson.JSON;
import com.zmn.base.common.data.common.dro.tags.TagsDRO;
import com.zmn.consts.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.manager.redis.RedisManager;
import com.zmn.market.common.enums.AppTypeEnum;
import com.zmn.market.common.model.dro.app.AppDRO;
import com.zmn.market.common.model.query.app.AppQuery;
import com.zmn.market.dubbo.DubboConsts;
import com.zmn.market.dubbo.interfaces.market.app.AppListRemoteService;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.messageV1.common.MessageSendBaseService;
import com.zmn.oms.business.interfaces.messageV1.wechat.MessageWeChatTemplateService;
import com.zmn.oms.common.constant.MessageConsts;
import com.zmn.oms.common.constant.MessageControlSwitchConsts;
import com.zmn.oms.common.constant.MessageRuleIdConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.constant.MessageQueueTopicConstant;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.dto.messageV1.SendMessageParams;
import com.zmn.oms.model.dto.messageV1.WeChatMessageDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.orderappbind.OrderThirdAppBind;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.uuc.common.dro.user.UserThirdDetailDRO;
import com.zmn.uuc.dubbo.interfaces.user.UserThirdListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class MessageWeChatTemplateServiceImpl extends AbstractMessageSendWeChat implements MessageWeChatTemplateService {
    private Logger logger = LoggerFactory.getLogger(MessageWeChatTemplateServiceImpl.class);

    @Autowired
    private MessageSendBaseService messageSendBaseService;
    @Autowired
    private RedisManager redisManager;
    @Resource
    private ZmnMQSender zmnMQSender;
    @Autowired
    private BaseCodeService baseCodeService;

    @DubboReference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private UserThirdListRemoteService userThirdListRemoteService;
    @DubboReference(version = DubboConsts.INTERFACE_VERSION , check = false)
    private AppListRemoteService appListRemoteService;

    private final static int COMPLETE_MSG_SEND_CONF_CODE = 1060;


    @Override
    public boolean sendWeChatTemplate(SendMessageParams param) {

        // 检查消息节点是否发送微信消息
        boolean disableSendMsg = MessageControlSwitchConsts.weixinDisableSendRuled.contains(param.getNodeMark());
        if (disableSendMsg) {
            logger.info("#oms#订单号={}send，该节点{}不发送微信消息 =======", param.getOrderId(), param.getNodeMark());
            return false;
        }

        OrderWork orderWork = param.getOrderWork();
        // 保外订单
        if (!Objects.equals(orderWork.getBizType(), GlobalConsts.BIZ_TYPE_F) &&
                Objects.equals(GlobalConsts.PLAT_MARK_YEYX, orderWork.getPlatWork())) {
           return false;
        }

        // 32854、34522渠道特殊处理，不发送微信，转换规则id
        boolean specialChannel = specialChannel(param);
        if (specialChannel) {
            return false;
        }

//  贺媛需求，去掉
//        // 判断是否非直营工程师
//        boolean isNotAgent = messageGetSendInfoService.isNotAgent(orderWork.getMasterId());
//        // 非直营工程师不发送完成微信消息
//        List<Integer> completeRules = Lists.newArrayList(MessageRuleIdConsts.ZMN_MSG_RULEID_COMPLETE, MessageRuleIdConsts.CNHB_MSG_RULEID_COMPLETE);
//        if (completeRules.contains(param.getRuleId()) && !isNotAgent) {
//            return false;
//        }

        // 处理必要条件
        WeChatMessageDTO weChatMessageDTO = getWeChatSendInfo(param);
        if (Objects.isNull(weChatMessageDTO)) {
            return false;
        }
        // 处理参数
        Map<String, String> smsMap = handleWeChatSendParams(param);
        if (Objects.isNull(smsMap)) {
            return true;
        }

        // 完成工单特殊处理：
        // 1、增加调整配置开关
        // 2、开关开启，需要调整为只针对【非会员用户】，在订单完成节点，调用10097这个场景发；
        //    开关关闭，需要调整为对【所有用户】在订单完成节点，调用10097这个场景发
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_COMPLETE, param.getRuleId()) &&
                !this.isSendCompleteMessage(param.getOrderId(), param.getSendUserId())) {

            logger.info("#oms#sendWeChatTemplate# [{}]-[{}] 根据配置，该订单不发送完成消息==========",
                    param.getOrderId(), param.getSendUserId());
            return true;
        }

        // 判断是否为完成消息
        if (Objects.equals(param.getRuleId(), MessageRuleIdConsts.ZMN_MSG_RULEID_COMPLETE) ||
                Objects.equals(param.getRuleId(), MessageRuleIdConsts.CNHB_MSG_RULEID_COMPLETE) ||
                Objects.equals(param.getRuleId(), MessageRuleIdConsts.SAAS_MSG_RULEID_COMPLETE) ||
                Objects.equals(param.getRuleId(), MessageRuleIdConsts.YEYX_MSG_RULEID_COMPLETE_TYPE_IN) ||
                Objects.equals(param.getRuleId(), MessageRuleIdConsts.YEYX_MSG_RULEID_COMPLETE_TYPE_OUT)) {

            // 查询并设置微信小程序的app id 及 open id
            this.setChatMessageMiniProgramParamByUserId(param.getSendUserId(), weChatMessageDTO);

            // 延迟15分钟, 发送节点已有延迟，不需要
            // weChatMessageDTO.setDelaySecond(900L);
        }

        // 发送消息
        weChatMessageDTO.setParams(JSON.toJSONString(smsMap));
        messageSendBaseService.sendWeiXinMessage(weChatMessageDTO);

        // 计价器报价需保存缓存（异步消息没法得到成功与否，走到此处默认为微信发送成功）
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_QUOTATION, param.getRuleId())) {
            // 在redis保存记录-72小时
            String redisKey = String.format(RedisKeyConsts.WECHAT_SEND_QUOTATION_TEMPLATE_KEY, String.valueOf(orderWork.getWorkId()), weChatMessageDTO.getOpenId());
            redisManager.setex(redisKey, JSON.toJSONString(smsMap), 3600 * 72);
        }

        // 下单成功后需要发送活动提醒
        if (Objects.equals(param.getRuleId(), MessageRuleIdConsts.ZMN_MSG_RULEID_ASSIGN_NO_LOGIN) ||
                Objects.equals(param.getRuleId(), MessageRuleIdConsts.ZMN_MSG_RULEID_ASSIGN)) {

            // 活动提醒rule id
            weChatMessageDTO.setRuleId(MessageConsts.ZMN_MSG_RULEID_ACTIVITY_REMINDER);

            logger.info("#oms#下单成功后发送活动提醒，{}{}",param.getOrderId(),JSON.toJSONString(weChatMessageDTO));

            // 查询并设置微信小程序参数
            this.setChatMessageMiniProgramParamByUserId(param.getSendUserId(), weChatMessageDTO);

            SendMessageParams copyParam = param;
            copyParam.setRuleId(MessageConsts.ZMN_MSG_RULEID_ACTIVITY_REMINDER);

            smsMap = handleWeChatSendParams(copyParam);
            weChatMessageDTO.setParams(JSON.toJSONString(smsMap));

            // 延迟7天
            weChatMessageDTO.setDelaySecond( 7 * 24 * 3600L);

            // 发送消息
            messageSendBaseService.sendWeiXinMessage(weChatMessageDTO);
        }

        return true;
    }

    @Override
    public boolean sendDesignatedUserWeChatTemplate(Long orderId, Integer ruleId, Long sendUserId) {
        return sendDesignatedOpenIdWeChatTemplate(orderId, ruleId, sendUserId, null);
    }

    @Override
    public boolean sendDesignatedOpenIdWeChatTemplate(Long orderId, Integer ruleId, Long sendUserId, String openId) {
        // 获取发送微信必要条件
        WeChatMessageDTO weChatMessageDTO = getWeChatMessageDesignatedInfo(orderId, ruleId, sendUserId, openId, null);
        if (Objects.isNull(weChatMessageDTO)) {
            logger.info("工单号={}，指定模板ruleId={}发送消息失败，缺失发送条件=======> ", orderId, ruleId);
            return false;
        }

        weChatMessageDTO.setRuleId(ruleId);
        weChatMessageDTO.setSkipType(GlobalConsts.YES);
        // 定金待支付，跳转H5
        // 尾款待支付，也跳转H5
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_DEPOSIT_PAY, ruleId)
                || Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_ORDER_PAY, ruleId)) {
            weChatMessageDTO.setSkipType(GlobalConsts.NO);
        }
        messageSendBaseService.sendWeiXinMessage(weChatMessageDTO);
        return true;
    }

    @Override
    public boolean sendDesignatedOpenIdWeChatTemplate(Long orderId, Integer ruleId, Long sendUserId, String openId, Long objectId) {
        // 获取发送微信必要条件
        WeChatMessageDTO weChatMessageDTO = getWeChatMessageDesignatedInfo(orderId, ruleId, sendUserId, openId, objectId);
        if (Objects.isNull(weChatMessageDTO)) {
            logger.info("工单号={}，指定模板ruleId={}发送消息失败，缺失发送条件=======> ", orderId, ruleId);
            return false;
        }

        weChatMessageDTO.setRuleId(ruleId);
        weChatMessageDTO.setSkipType(GlobalConsts.YES);
        // 定金待支付，跳转H5
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_DEPOSIT_PAY, ruleId)
                || Objects.equals(MessageConsts.ZMN_WECHAT_MSG_RULEID_ORDER_ACCEPTANCE_DEPOSIT, ruleId)
                || Objects.equals(MessageConsts.ZMN_WECHAT_MSG_RULEID_ORDER_ACCEPTANCE_PAYMENT, ruleId)
                || Objects.equals(MessageConsts.ZMN_WECHAT_MSG_RULE_ID_QUOTATION_THREE_PAYMENT, ruleId)) {
            weChatMessageDTO.setSkipType(GlobalConsts.NO);
        }
        messageSendBaseService.sendWeiXinMessage(weChatMessageDTO);
        return true;
    }

    @Override
    public void sendWeChatPrivateTrafficMsg(Long orderId, Integer platWork, Integer channelId, Long userId, String openId) {
        if (StringUtils.isBlank(openId)) {
            log.info("#oms#saas#[{}]尾款支付后发送私域流量消息发送失败，没有openId", orderId);
            return;
        }
        // 发送消息给 saas, saas 发送关注企业微信消息
        String thirdAppId = messageGetSendInfoService.getOrderWeChatThirdAppId(orderId, platWork);
        if (StringUtils.isBlank(thirdAppId)) {
            log.info("#oms#saas#[{}]尾款支付后发送私域流量消息发送失败，没有thirdAppId", orderId);
            return;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("orderId", orderId);
        map.put("channelId", channelId);
        map.put("userId", userId);
        map.put("thirdAppId", thirdAppId);
        map.put("openId", openId);

        String key = String.format("%s-order-%s", orderId, DateUtil.getNowTimestamp());
        log.info("#oms#saas#尾款支付后发送私域流量消息-TOPIC = [{}] KEY[{}]入参{}", MessageQueueTopicConstant.ZMN_TOPIC_OMS, key, JSON.toJSONString(map));
        zmnMQSender.send(MessageQueueTopicConstant.ZMN_TOPIC_OMS, OmsMqTagConsts.SAAS_TAG_PRIVATE_TRAFFIC_MSG, key, JSON.toJSONString(map));
    }


    @Override
    public boolean sendDesignatedWeChatTemplate(Long orderId, Long workId, Integer ruleId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            return false;
        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        if (Objects.isNull(orderDetail)) {
            return false;
        }

        // 初始化下单用户信息
        OrderThirdAppBind orderThirdAppBind = Optional.ofNullable(messageGetSendInfoService.getOrderWeChatBindInfoForOrderBy(orderWork.getOrderId(), orderWork.getPlatWork()))
                .orElse(messageGetSendInfoService.getRemoteThirdAppBind(orderId, orderWork.getUserId(), orderWork.getCityId(), Optional.ofNullable(orderWork.getPlat()).orElse(orderWork.getPlatWork())));
        if (Objects.isNull(orderThirdAppBind) || StringUtils.isBlank(orderThirdAppBind.getThirdAppId())) {
            logger.info("#oms#message#orderId={}={}，场景ID:{} 没有查到绑定的公众号信息", workId, ruleId);
            return false;
        }

        SendMessageParams sendMessageParams = new SendMessageParams();
        sendMessageParams.setOrderId(orderId);
        sendMessageParams.setWorkId(workId);
        sendMessageParams.setRuleId(ruleId);
        sendMessageParams.setStatus(orderWork.getStatus());
        sendMessageParams.setResultStatus(orderWork.getResultStatus());
        sendMessageParams.setOrderWork(orderWork);
        sendMessageParams.setOrderDetail(orderDetail);
        sendMessageParams.setPlat(Optional.ofNullable(orderWork.getPlatWork()).orElse(orderWork.getPlat()));
        sendMessageParams.setRuleId(ruleId);

        sendMessageParams.setThirdAppId(orderThirdAppBind.getThirdAppId());
        sendMessageParams.setThirdAppName(orderThirdAppBind.getThirdAppName());

        boolean isSendSuccess = false;

        // 发送下单用户
        if (NumberUtil.isNotNullOrZero(orderWork.getUserId())) {
            sendMessageParams.setSendUserId(orderWork.getUserId());
            isSendSuccess = isSendSuccess || this.sendWeChatTemplate(sendMessageParams);
        }

        // 发送扫码用户
        if (NumberUtil.isNotNullOrZero(orderWork.getVisitUserId())) {
            sendMessageParams.setSendUserId(orderWork.getVisitUserId());
            isSendSuccess = isSendSuccess || this.sendWeChatTemplate(sendMessageParams);
        }

        logger.info("#oms#message#orderId={}={}，场景ID:{} 消息结果：{}", workId, ruleId, isSendSuccess);
        return isSendSuccess;
    }

    /**
     * 通过用户id，查找并设置微信消息里小程序数据
     * @param userId
     */
    private void setChatMessageMiniProgramParamByUserId(Long userId, WeChatMessageDTO weChatMessageDTO) {

        if (NumberUtil.isNullOrZero(userId)) {
            return;
        }

        // 通过用户Id查找关联的第三方
        logger.info("#setChatMessageMiniProgramParamByUserId#UserThirdListRemoteService#listThirdByUserId# 入参{}", userId);
        ResponseDTO<List<UserThirdDetailDRO>> listResponseDTO = userThirdListRemoteService.listThirdByUserId(userId);
        logger.info("#setChatMessageMiniProgramParamByUserId#UserThirdListRemoteService#listThirdByUserId# 出参{}", listResponseDTO.toString());
        if (!listResponseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(listResponseDTO.getData())) {
            return;
        }

        for (UserThirdDetailDRO userThirdDetailDRO : listResponseDTO.getData()) {

            // 通过app id 查找对应信息
            AppQuery appQuery = new AppQuery();
            appQuery.setThirdAppId(userThirdDetailDRO.getAppId());
            logger.info("#setChatMessageMiniProgramParamByUserId#appListRemoteService#appListRemoteService# 入参{}", appQuery.toString());
            ResponseDTO<List<AppDRO>> appDROListResponseDTO = appListRemoteService.listByQuery(appQuery);
            logger.info("#setChatMessageMiniProgramParamByUserId#appListRemoteService#appListRemoteService# 出参{}", appDROListResponseDTO.toString());
            if (!appDROListResponseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(appDROListResponseDTO.getData())) {
                continue;
            }

            // 判断是否为小程序
            for (AppDRO appDRO : appDROListResponseDTO.getData()) {
                if (Objects.equals(appDRO.getAppTypeId(), AppTypeEnum.MINI_PROGRAM_ACCOUNT_TYPE.getCode())) {

                    weChatMessageDTO.setMiniProgramAppId(appDRO.getThirdAppId());
                    weChatMessageDTO.setMiniProgramOpenId(userThirdDetailDRO.getOpenId());
                    logger.info("WeChatMessageDTO 设置微信小程序id和openId,{}{}", appDRO.getThirdAppId(), userThirdDetailDRO.getOpenId());

                    return;
                }
            }
        }
    }

    /**
     * 判断是否发送完成消息，需求逻辑：
     * 1、增加调整配置开关
     * 2、开关开启，需要调整为只针对【非会员用户】，在订单完成节点，调用10097这个场景发；开关关闭，
     *    需要调整为对【所有用户】在订单完成节点，调用10097这个场景发。
     *
     * @param orderId
     * @param userId
     * @return
     */
    private boolean isSendCompleteMessage(Long orderId, Long userId) {

        // 参数判断
        if (NumberUtil.isNullOrZero(userId)) {
            return false;
        }

        try {

            // 配置查询及判断
            logger.info("#MessageWeChatTemplateService#isSendCompleteMessage# check config, orderId={}", orderId);

            do {
                // 查询所有配置
                List<TagsDRO> tagsDROList = baseCodeService.listBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN,
                        COMPLETE_MSG_SEND_CONF_CODE, null, null);
                if (CollectionUtil.isNullOrEmpty(tagsDROList)) {
                    return true;
                }

                TagsDRO confTagsDRO = null;
                for (TagsDRO tagsDRO : tagsDROList) {
                    // 判断配置是否开启
                    if (NumberUtil.isNullOrZero(tagsDRO.getTwoTypeId())) {
                        confTagsDRO = tagsDRO;
                        break;
                    }
                }

                // 配置开关
                if (Objects.isNull(confTagsDRO) || !Objects.equals(confTagsDRO.getStatus(), GlobalConsts.YES)) {
                    return true;
                }

            } while (false);

            if (!isMemberUser(userId)) {
                return true;
            }
        } catch (Exception e) {
            logger.info("#MessageWeChatTemplateService#isSendCompleteMessage# exception:[{}]", e.getMessage());
        }

        return false;
    }
}
